package com.fingard.dsp.bank.directbank.hxb11;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

public class HXB11BatPayRec extends HXB11Base implements IBatPayRec {

	@Override
	public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
		RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);

		Date tmpDateNow = new Date();
		
		String tmpPaySendDate = Format.Date8Format.format(p_req1988.getPayDateTime());
		// 上传文件名命名规则: PL+文件类型 ： 1代扣，2代付+保险公司代码:如101+业务日期必须为当日:如20110823+序号:左补零001
		String tmpUploadFileName = "PL" + "2" + bankFront.corpNo + tmpPaySendDate + "001" + ".xml";
		String tmpLocalMarkPath = getDataFileDirectory(p_req1988.getPayDateTime()) + File.separator + tmpUploadFileName;
		WriteBankLogLn2("批量代收请求文件保存本机路径: " + tmpLocalMarkPath);
		//一天只能上传一个文件
		if (FileHelper.existFile(tmpLocalMarkPath)) {
			retAts.respCode = "0";
			retAts.respInfo = "当日已上传文件,华夏银保通一天仅支持一个文件,请勿重复上传!";
			retAts.reqSeqID = p_req1988.reqBatchNO;
			retAts.transState = PaymentState.FAIL_Batch;
			retAts.payInfoCode = FailCode.E9981;
			retAts.writeRetToATS();
			return retAts;
		}

		XmlTextWriter xmlWriter = new XmlTextWriter();// 发银行报文的XML对象

		xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"GBK\"?>");
		xmlWriter.writeStartElement("DOCUMENT");
		xmlWriter.writeStartElement("HEAD");

		xmlWriter.writeElementString("BANKCODE", bankFront.org); // 银行代码
		xmlWriter.writeElementString("INSUID", bankFront.corpNo); // 保险公司代码
		xmlWriter.writeElementString("TRANSRDATE", Format.Date8Format.format(tmpDateNow)); // 交易日期
		xmlWriter.writeElementString("TRANSRTIME", Format.Time9Format.format(tmpDateNow)); // 对账时间
		xmlWriter.writeElementString("TRANSCOUNTS", p_req1988.totalNum);// 交易总笔数
		xmlWriter.writeElementString("TRANSAMOUNTS", p_req1988.totalAmt);// 交易总金额
		xmlWriter.writeElementString("FILETYPE", "2");
		xmlWriter.writeElementString("MAC", "");

		xmlWriter.writeEndElement();

		xmlWriter.writeStartElement("BODY");
		while (p_req1988.readRecord()) {
			// tmpRdCount++;
			ReqPayRecDetail tmpDetail = p_req1988.readedDetail;
			XElement tmpXElement = new XElement("DETAIL", "");
			tmpXElement.addChild(new XElement("PAYACC", tmpDetail.recAct));// 卡号
			tmpXElement.addChild(new XElement("INVESTORNAME", tmpDetail.recName));// 户名
			tmpXElement.addChild(new XElement("INSURNO", tmpDetail.sourceNoteCode));// 保险单号
			tmpXElement.addChild(new XElement("PAYAMOUNTS", tmpDetail.payAmount));// 金额
			// 根据代收付用途确认业务类型
			String BusinessCode = this.getBankConfig().getMapValueByKey("BUSINESS_CODE_1988", tmpDetail.useType);
			tmpXElement.addChild(new XElement("BUSINESSCODE", BusinessCode));// 业务类型
			tmpXElement.addChild(new XElement("ZONENO", tmpDetail.recArea));// 地区代码
			tmpXElement.addChild(new XElement("SERIALNO", tmpDetail.askNumber));// 核心的唯一标识码
			nodeAnalysis(tmpDetail.srcXElement, tmpXElement, getCharset());
			xmlWriter.writeXElement(tmpXElement);
		}
		xmlWriter.writeEndElement();
		xmlWriter.writeEndElement();

		WriteBankLogLn("批量付请求文件内容:\r\n" + xmlWriter.getSbXml().toString());

		FileHelper.writeFile(tmpLocalMarkPath, xmlWriter.getSbXml().toString(), getCharset());

		// 上送银保通服务器
		FtpSet ftpSet = bankFront.getFtpSet("bat");

		FtpReceiver ftpReceiver = null;
		String requestType = getBankConfig().getValueAsString("requestType");
		if (requestType != null && "SFTP".equals(requestType)) {
			SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
			String sftpFilePath = StringHelper.trimEnd(ftpSet.upDir, "/") + "/" + tmpUploadFileName;
			ftpReceiver = sftpPortClient.uploadFile("", tmpLocalMarkPath, sftpFilePath);
			sftpPortClient.disconnect();
		} else {
			FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
			ftpReceiver = ftpPortClient.uploadFile(tmpLocalMarkPath, tmpUploadFileName);
			ftpPortClient.disconnect();
		}

		retAts.respCode = "0";
		retAts.reqSeqID = p_req1988.reqBatchNO;
		if (!ftpReceiver.isCompleted) {
			retAts.respCode = "-1";
			retAts.respInfo = ftpReceiver.connMsg;
		} else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
			retAts.respInfo = "上传失败";
			retAts.transState = "BatchFailed";
			retAts.payInfoCode = "E9999";
		} else {
			retAts.respInfo = "上传成功";
			retAts.transState = "Uploaded";
			retAts.payInfoCode = "I4001";
		}

		retAts.writeRetToATS();
		return retAts;
	}

	@Override
	public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
		RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
		retAts.reqSeqID = p_req1998.reqBatchNO;

		try {
			// 下载文件名命名规则: RPL+文件类型 ： 1代扣，2代付+保险公司代码:如101+业务日期必须为当日:如20110823+序号:左补零001
			String tmpPaySendDate = Format.Date8Format.format(p_req1998.getBgnDateTime());
			String tmpDownFileName = "RPL" + "2" + bankFront.corpNo + tmpPaySendDate + "001" + ".xml";
			String tmpLocalMarkPath = createTempFileDirectory() + File.separator + tmpDownFileName;
			WriteBankLogLn2("批次结果文件保存本地路径: " + tmpLocalMarkPath);

			FtpSet ftpSet = bankFront.getFtpSet("bat");
			FtpReceiver ftpReceiver = null;
			String requestType = getBankConfig().getValueAsString("requestType");
			if (requestType != null && "SFTP".equals(requestType)) {
				String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + tmpDownFileName;
				WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
				SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
				ftpReceiver = sftpPortClient.downloadFile("", sftpFilePath, tmpLocalMarkPath);
				sftpPortClient.disconnect();
			} else {
				FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
				ftpReceiver = ftpPortClient.downloadFile(tmpDownFileName, tmpLocalMarkPath);
				ftpPortClient.disconnect();
			}

			if (ftpReceiver.isCompleted) {
				String tmpStrRet = FileHelper.readFileText(tmpLocalMarkPath, getCharset());
				WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);

				if (StringHelper.hasAnyChar(tmpStrRet)) {
					retAts.respCode = "0";
					retAts.reqSeqID = p_req1998.reqBatchNO;
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet, tmpSbMsg);
					if (tmpBkReader != null) {
						while (tmpBkReader.read("/DOCUMENT/BODY/DETAIL")) {
							RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

							tmpRetDetail.recName = tmpBkReader.readedXElement.getSingleText("INVESTORNAME");
							tmpRetDetail.recAct = tmpBkReader.readedXElement.getSingleText("PAYACC");
							tmpRetDetail.payAmount = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("PAYAMOUNTS"));
							tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("SERIALNO");
							tmpRetDetail.result = tmpBkReader.readedXElement.getSingleText("RETCODE");
							tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("RETCODE");
							tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("RETMSG");
							retAts.writeRetDetail(tmpRetDetail);
						}
					} else {
						retAts.respCode = "-1";
						retAts.respInfo = tmpBkReader.toString();
					}
					
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "本地批次结果文件内容为空!";
				}
			} else {
				retAts.respCode = "-1";
				retAts.respInfo = "批次结果文件下载失败:" + ftpReceiver.connMsg;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeAfterDetail();
		return retAts;
	}

	@Override
	public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {

		RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req9188.reqHeader);

		Date tmpDateNow = new Date();
		
		String tmpPaySendDate = Format.Date8Format.format(p_req9188.getPayDateTime());
		// 上传文件名命名规则: PL+文件类型 ： 1代扣，2代付+保险公司代码:如101+业务日期必须为当日:如20110823+序号:左补零001
		String tmpUploadFileName = "PL" + "1" + bankFront.corpNo + tmpPaySendDate + "001" + ".xml";
		String tmpLocalMarkPath = getDataFileDirectory(p_req9188.getPayDateTime()) + File.separator + tmpUploadFileName;
		WriteBankLogLn2("批量代收请求文件保存本机路径: " + tmpLocalMarkPath);
		//一天只能上传一个文件
		if (FileHelper.existFile(tmpLocalMarkPath)) {
			retAts.respCode = "0";
			retAts.respInfo = "当日已上传文件,华夏银保通一天仅支持一个文件,请勿重复上传!";
			retAts.reqSeqID = p_req9188.reqBatchNO;
			retAts.transState = PaymentState.FAIL_Batch;
			retAts.payInfoCode = FailCode.E9981;
			retAts.writeRetToATS();
			return retAts;
		}

		XmlTextWriter xmlWriter = new XmlTextWriter();// 发银行报文的XML对象

		xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"GBK\"?>");
		xmlWriter.writeStartElement("DOCUMENT");
		xmlWriter.writeStartElement("HEAD");

		xmlWriter.writeElementString("BANKCODE",  bankFront.org); // 银行代码
		xmlWriter.writeElementString("INSUID", bankFront.corpNo); // 保险公司代码
		xmlWriter.writeElementString("TRANSRDATE", Format.Date8Format.format(tmpDateNow)); // 交易日期
		xmlWriter.writeElementString("TRANSRTIME", Format.Time9Format.format(tmpDateNow)); // 对账时间
		xmlWriter.writeElementString("TRANSCOUNTS", p_req9188.totalNum);// 交易总笔数
		xmlWriter.writeElementString("TRANSAMOUNTS", p_req9188.totalAmt);// 交易总金额
		xmlWriter.writeElementString("FILETYPE", "1");
		xmlWriter.writeElementString("MAC", "");

		xmlWriter.writeEndElement();

		xmlWriter.writeStartElement("BODY");
		while (p_req9188.readRecord()) {
			// tmpRdCount++;
			ReqPayRecDetail tmpDetail = p_req9188.readedDetail;
			XElement tmpXElement = new XElement("DETAIL", "");
			tmpXElement.addChild(new XElement("PAYACC", tmpDetail.payAct));// 卡号
			tmpXElement.addChild(new XElement("INVESTORNAME", tmpDetail.payName));// 户名
			tmpXElement.addChild(new XElement("INSURNO", tmpDetail.sourceNoteCode));// 保险单号
			tmpXElement.addChild(new XElement("PAYAMOUNTS", tmpDetail.payAmount));// 金额
			// 根据代收付用途确认业务类型
			String BusinessCode = this.getBankConfig().getMapValueByKey("BUSINESS_CODE_9188", tmpDetail.useType);
			tmpXElement.addChild(new XElement("BUSINESSCODE", BusinessCode));// 业务类型
			tmpXElement.addChild(new XElement("ZONENO", tmpDetail.payArea));// 地区代码
			tmpXElement.addChild(new XElement("SERIALNO", tmpDetail.askNumber));// 核心的唯一标识码
			nodeAnalysis(tmpDetail.srcXElement, tmpXElement, getCharset());
			xmlWriter.writeXElement(tmpXElement);
		}
		xmlWriter.writeEndElement();
		xmlWriter.writeEndElement();

		WriteBankLogLn("批量代收请求文件内容:\r\n" + xmlWriter.getSbXml().toString());

		FileHelper.writeFile(tmpLocalMarkPath, xmlWriter.getSbXml().toString(), getCharset());

		// 上送银保通服务器
		FtpSet ftpSet = bankFront.getFtpSet("bat");

		FtpReceiver ftpReceiver = null;
		String requestType = getBankConfig().getValueAsString("requestType");
		if (requestType != null && "SFTP".equals(requestType)) {
			SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
			String sftpFilePath = StringHelper.trimEnd(ftpSet.upDir, "/") + "/" + tmpUploadFileName;
			ftpReceiver = sftpPortClient.uploadFile("", tmpLocalMarkPath, sftpFilePath);
			sftpPortClient.disconnect();
		} else {
			FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
			ftpReceiver = ftpPortClient.uploadFile(tmpLocalMarkPath, tmpUploadFileName);
			ftpPortClient.disconnect();
		}

		retAts.respCode = "0";
		retAts.reqSeqID = p_req9188.reqBatchNO;
		if (!ftpReceiver.isCompleted) {
			retAts.respCode = "-1";
			retAts.respInfo = ftpReceiver.connMsg;
		} else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
			retAts.respInfo = "上传失败";
			retAts.transState = "BatchFailed";
			retAts.payInfoCode = "E9999";
		} else {
			retAts.respInfo = "上传成功";
			retAts.transState = "Uploaded";
			retAts.payInfoCode = "I4001";
		}

		retAts.writeRetToATS();
		return retAts;
	}

	@Override
	public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
		RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req9198.reqHeader);
		retAts.reqSeqID = p_req9198.reqBatchNO;

		try {
			// 下载文件名命名规则: RPL+文件类型 ： 1代扣，2代付+保险公司代码:如101+业务日期必须为当日:如20110823+序号:左补零001
			String tmpPaySendDate = Format.Date8Format.format(p_req9198.getBgnDateTime());
			String tmpDownFileName = "RPL" + "1" + bankFront.corpNo + tmpPaySendDate + "001" + ".xml";
			String tmpLocalMarkPath = createTempFileDirectory() + File.separator + tmpDownFileName;
			WriteBankLogLn2("批次结果文件保存本地路径: " + tmpLocalMarkPath);

			FtpSet ftpSet = bankFront.getFtpSet("bat");
			FtpReceiver ftpReceiver = null;
			String requestType = getBankConfig().getValueAsString("requestType");
			if (requestType != null && "SFTP".equals(requestType)) {
				String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + tmpDownFileName;
				WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
				SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
				ftpReceiver = sftpPortClient.downloadFile("", sftpFilePath, tmpLocalMarkPath);
				sftpPortClient.disconnect();
			} else {
				FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
				ftpReceiver = ftpPortClient.downloadFile(tmpDownFileName, tmpLocalMarkPath);
				ftpPortClient.disconnect();
			}

			if (ftpReceiver.isCompleted) {
				String tmpStrRet = FileHelper.readFileText(tmpLocalMarkPath, getCharset());
				WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);

				if (StringHelper.hasAnyChar(tmpStrRet)) {
					retAts.respCode = "0";
					retAts.reqSeqID = p_req9198.reqBatchNO;
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet, tmpSbMsg);
					if (tmpBkReader != null) {
						while (tmpBkReader.read("/DOCUMENT/BODY/DETAIL")) {
							RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

							tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("INVESTORNAME");
							tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("PAYACC");
							tmpRetDetail.payAmount = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("PAYAMOUNTS"));
							tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("SERIALNO");
							tmpRetDetail.result = tmpBkReader.readedXElement.getSingleText("RETCODE");
							tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("RETCODE");
							tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("RETMSG");
							retAts.writeRetDetail(tmpRetDetail);
						}
					} else {
						retAts.respCode = "-1";
						retAts.respInfo = tmpBkReader.toString();
					}
					
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "本地批次结果文件内容为空!";
				}
			} else {
				retAts.respCode = "-1";
				retAts.respInfo = "批次结果文件下载失败:" + ftpReceiver.connMsg;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeAfterDetail();
		return retAts;
	}

}
